//
//  BluetoothManager+Extensions.swift
//  DaRings
//
//  Created by HFY on 2022/11/13.
//

import UIKit
import MYModule
import CRPSmartRing
import SwiftDate


// MARK: - 单天数据同步
public extension BluetoothManager {
    
   
    /// 计算天数差
    /// - Parameter date: 日期
    /// - Returns: 差额多少天
    fileprivate func dayComponents(of startDate: Date, to date: Date) ->Int {
        
        // 算出来date距离今天多少天
        let calendar = Calendar.current
        let endDate = date.sqlDate()
        
        var dateComponents = calendar.dateComponents([.day], from: endDate, to: startDate).day!
        if dateComponents < 0 {
            dateComponents = 0
        }
        return dateComponents
    }
    
    /// 获取一天睡眠
    /// - Parameter date: 日期
    func getSleepData(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        
        // 晚上8点以后统计的是明天的睡眠
        var varStartDate = startDate
        var varToDate = date
        
        
        
        if varStartDate.hour >= SleepModel.constSleepStart {
            // 日期 + 1 
            varStartDate = startDate.dateAtStartOf(.day) + 1.days
            varToDate = date.dateAtStartOf(.day) + 1.days
            
        }
            
        // 注意： 晚上20点以后统计的是明天的睡眠数据
        // 不是今天/明天数据，数据库已有就不需要指令获取
        if let model = SleepModel.day(date: varToDate), model.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: model.updateTime)
            // 不是今天不是明天
            if !varToDate.isToday && !varToDate.isTomorrow && updateDate.isAfterDate(model.date, granularity: .day) {
                sucess?()
                return
            }
            
            
//            else {
//
//                // 今天或明天 1分钟最多获取一次
//                let com = Date().timeIntervalSince1970 - model.updateTime
//                if !forcedUpdate && com < 60 && model.updateTime != 0 {
//                    sucess?()
//                    return
//                }
//            }
            
            
        }
        
        let dateComponents = dayComponents(of: varStartDate, to: varToDate)
        
        // 获取今天前多少天的一天睡眠数据
        BluetoothManager.shared.getSleepData(dateComponents) { model, error in
            var sleepModel: SleepModel?
            
            var aDate = varStartDate
            
            if model.day > 0 {
                aDate = varStartDate - model.day.days
            }
            

            if let model = SleepModel.day(date: aDate) {
                sleepModel = model
            } else {
                sleepModel = SleepModel()
                
            }
            
            // 判断数据是否该存储
            if model.day != 0 && model.detail.isEmpty && sleepModel?.isEmpty == false {
                sucess?()
                return
            }
            
            sleepModel?.adress = DeviceInfo.current().adress ?? ""
            sleepModel?.date = aDate.sqlDate()
            sleepModel?.deep = model.deep
            sleepModel?.light = model.light
            sleepModel?.rem = model.rem
            sleepModel?.updateTime = Date().timeIntervalSince1970
            
            let detail = [SleepDetailModel].deserialize(from: model.detail)
            sleepModel?.detail = detail?.compactMap({ $0 }) ?? []
            
            sleepModel?.updateData()
            
            sucess?()
        }
        
    }
    
   
    /// 体温
    /// - Parameters:
    ///   - startDate: 开始日期
    ///   - date: 结束日期
    ///   - sucess: block
    func getSleepTemperatureData(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        
        if let model = TemperatureModel.day(date: date), model.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: model.updateTime)
            // 非今日的数据, 数据库查询, 如果更新时间天大于所属的天，就不需要指令同步
            if !model.date.isToday && updateDate.isAfterDate(model.date, granularity: .day) {
                sucess?()
                return
                
            }
            
//            else {
//                // 今天或5分钟最多获取一次
//                let com = Date().timeIntervalSince1970 - model.updateTime
//                if !forcedUpdate && com < 300 && model.updateTime != 0 {
//                    sucess?()
//                    return
//                }
//            }

        }
        
        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getSleepTemperatureData(day: dateComponents) { model, error in
            
            var temperatureModel: TemperatureModel?
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            if let model = TemperatureModel.day(date: aDate) {
                
                temperatureModel = model
            } else {
                
                temperatureModel = TemperatureModel()
            }
            
            let isEmpty = model.tempeartures.filter { $0 > 30 && $0 < 42 }.isEmpty
            if model.day != 0 && isEmpty && temperatureModel?.isEmpty == false {
                sucess?()
                return
            }
            
            temperatureModel?.adress = DeviceInfo.current().adress ?? ""
            temperatureModel?.date = aDate.sqlDate()
            temperatureModel?.tempeartures = model.tempeartures
            temperatureModel?.updateData()
            
            sucess?()
            
        }
        
    }
    
    /// 睡眠活动量1分钟归档
    /// - Parameters:
    ///   - startDate: 开始日期
    ///   - date: 结束日期
    func getSleepActivityArchiveData(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 数据库有，除了今天 数据不为空就不需要指令获取
        if let amountActivityModel = AmountActivityModel.day(date: date), amountActivityModel.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: amountActivityModel.updateTime)
            // 非今日的数据, 数据库查询, 如果更新时间天大于所属的天，就不需要指令同步
            if !amountActivityModel.date.isToday && updateDate.isAfterDate(amountActivityModel.date, granularity: .day) {
                sucess?()
                return
            }
//            else {
//
//                // 今天1分钟最多获取一次
//                let com = Date().timeIntervalSince1970 - amountActivityModel.updateTime
//                if !forcedUpdate && com < 60 && amountActivityModel.updateTime != 0 {
//                    sucess?()
//                    return
//                }
//            }
            
        }
        
        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getSleepActivityArchiveData(dateComponents, { model, error in
            
            var amountActivityModel: AmountActivityModel?
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            
            if let model = AmountActivityModel.day(date: aDate) {
                amountActivityModel = model
            } else {
                amountActivityModel = AmountActivityModel()
                amountActivityModel?.date = aDate.sqlDate()
                
            }
            amountActivityModel?.adress = DeviceInfo.current().adress ?? ""
            let activitys: [Int] = model.activitys.map({
                
                /// 固件给过来的值中 最高位代表是是否佩戴，暂时固定减去 128，得到是实际的值
                if $0 <= 128 {
                    return 0
                }
                
                return $0 - 128
                
            })
            
            if model.day != 0 && activitys.filter({ $0 > 0 }).isEmpty && amountActivityModel?.isEmpty == false {
                sucess?()
                return
            }
            
            amountActivityModel?.activitys = activitys
            
            amountActivityModel?.updateData()
            
            sucess?()
            
        })
        
    }
    
    
    /// 获取实时心率
    /// - Parameter date: 日期
    func getTimingHeartRate(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        
        if let heartRateModel = HeartRateModel.day(date: date), heartRateModel.adress == DeviceInfo.current().adress {

            let updateDate = Date(timeIntervalSince1970: heartRateModel.updateTime)
            if !date.isToday && updateDate.isAfterDate(heartRateModel.date, granularity: .day) {
                
                sucess?()
                return
                
            }
//            else {
//
//                let com = Date().timeIntervalSince1970 - heartRateModel.updateTime
//                if !forcedUpdate && com < 30 * 60 && heartRateModel.updateTime != 0 {
//                    sucess?()
//                    return
//                }
//            }
        }

        
        let dateComponents = dayComponents(of: startDate, to: date)
        
        BluetoothManager.shared.getTimingHeartRate(dateComponents) { model, error in
            
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            
            let heartRateModel = HeartRateModel.day(date: aDate) ?? HeartRateModel()
            let hearts = self.stride(data: model.hearts, from: 0, range: 6)
            
            if model.day != 0 && hearts.filter({ $0 > 0 }).isEmpty && heartRateModel.isEmpty == false {
                sucess?()
                return
            }
            
            heartRateModel.adress = DeviceInfo.current().adress ?? ""
            heartRateModel.date = aDate.sqlDate()
            
            // 传过来的数组是288个，但是半小时只测量一次，所以 每5个点中取一个真实的值
            // 数组分割 5个一组
            
            heartRateModel.hearts = hearts
            
            heartRateModel.updateTime = Date().timeIntervalSince1970
            heartRateModel.updateData()
            
            
            sucess?()
        }
    }
    
    /// 获取全天 HRV
    func getTimingHRV(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        
        if let model = HRVModel.day(date: date),  model.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: model.updateTime)
            if !date.isToday && updateDate.isAfterDate(model.date, granularity: .day) {
                
                sucess?()
                return
                
            }
            
//            else {
//
//                let com = Date().timeIntervalSince1970 - model.updateTime
//                if !forcedUpdate && com < 30 * 60 && model.updateTime != 0 {
//                    sucess?()
//                    return
//                }
//            }
        }
            

        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getTimingHRV(dateComponents) { model, error in
            
            
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            
            
            let hrvModel = HRVModel.day(date: aDate) ?? HRVModel()
            
            let hrvs = self.stride(data: model.hrvs, from: 0, range: 6)
            if model.day != 0 && hrvs.filter({ $0 > 0 }).isEmpty && hrvModel.isEmpty == false {
                sucess?()
                return
            }
            
            hrvModel.adress = DeviceInfo.current().adress ?? ""
            hrvModel.date = aDate.sqlDate()
            hrvModel.updateTime = Date().timeIntervalSince1970
            
            hrvModel.hrvs = hrvs
            hrvModel.updateData()
            
            sucess?()
        }
        
    }
    
    /// 获取全天血氧
    func getTimingO2(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        
        if let model = BloodOxygenModel.day(date: date), model.adress == DeviceInfo.current().adress {
            // 不是今天
            let updateDate = Date(timeIntervalSince1970: model.updateTime)
            if !date.isToday && updateDate.isAfterDate(model.date, granularity: .day) {
                sucess?()
                return
                
            }
            
//            else {
//
//                let com = Date().timeIntervalSince1970 - model.updateTime
//                if !forcedUpdate && com < 30 * 60 && model.updateTime != 0 && !model.isEmpty {
//                    sucess?()
//                    return
//                }
//            }
//            return
        }
        
        
        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getTimingO2(dateComponents) { model, error in
            
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            
            let bloodOxygenModel = BloodOxygenModel.day(date: aDate) ?? BloodOxygenModel()
            
            if model.day != 0 && model.o2s.filter({ $0 > 0 }).isEmpty && bloodOxygenModel.isEmpty == false {
                sucess?()
                return
            }
            
            bloodOxygenModel.adress = DeviceInfo.current().adress ?? ""
            bloodOxygenModel.date = aDate.sqlDate()
            bloodOxygenModel.o2s = model.o2s
            bloodOxygenModel.updateTime = Date().timeIntervalSince1970
            bloodOxygenModel.updateData()
            
            sucess?()
        }
        
    }
    
    
    /// 活动历史数据
    func getTrainingData(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 数据库有，就不需要指令获取 !date.isToday, !model.isEmpty
        if let model = ActivityModel.day(date: date), model.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: model.updateTime)
            if !model.date.isToday && updateDate.isAfterDate(model.date, granularity: .day) {
                
                sucess?()
                return
                
            }
            
        }
        
        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getTrainingData(dateComponents) { model, error in
            

           let time = Int(Double(model.step) * 0.008 * 60.0)

            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            var activityModel: ActivityModel
            if let model = ActivityModel.day(date: aDate) {
                activityModel = model
            } else {
                
                activityModel = ActivityModel()
            }
            
            if activityModel.goalStep == 0 || activityModel.goalCalorie == 0 || activityModel.goalTime == 0 {
                // 查询 目标设置
                let goalModel = ExerciseGoalsModel.currentGoal(weekDay: date.weekday)
                
                let step_target = goalModel.step
                let calories_target = goalModel.kcal
                let duration_target = goalModel.exerciseTime
                
                activityModel.goalStep = step_target
                activityModel.goalCalorie = calories_target
                activityModel.goalTime = duration_target
                
            }
            
            if model.day != 0 && model.step == 0 && activityModel.isEmpty == false {
                sucess?()
                return
            }
            
            activityModel.adress = DeviceInfo.current().adress ?? ""
            activityModel.date = aDate.sqlDate()
            activityModel.step = model.step
            // 距离单位是厘米
            activityModel.distance = model.distance/100
            activityModel.time = time
            // 卡路里获取到的是小卡
            activityModel.calorie = model.cal/10000
            
            activityModel.updateData()
            
            sucess?()
        }
        
    }
    
    
    /// 一天活动归档数据(半小时归档)
    /// - Parameter date: 日期
    func getStepArchiveData(of startDate: Date = Date().sqlDate(), to date: Date, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 数据库查询
        if let activityModel = StepArchiveModel.day(date: date), activityModel.adress == DeviceInfo.current().adress {
            
            let updateDate = Date(timeIntervalSince1970: activityModel.updateTime)
            if !activityModel.date.isToday && updateDate.isAfterDate(activityModel.date, granularity: .day) {
                sucess?()
                return
                
            }
            
//            else {
//                
//                // 上一次存储时差相差不超过半小时，不需要指令再次获取
//                let com = Date().timeIntervalSince1970 - activityModel.updateTime
//                if !forcedUpdate && com < 30 * 60 && activityModel.updateTime != 0 && !activityModel.isEmpty {
//                    sucess?()
//                    return
//                }
//            }
            
        }
        
        let dateComponents = dayComponents(of: startDate, to: date)
        BluetoothManager.shared.getStepArchiveData(dateComponents) { model, error in
            
            var stepArchiveModel: StepArchiveModel
            var aDate = startDate
            if model.day > 0 {
                aDate = startDate - model.day.days
            }
            if let model = StepArchiveModel.day(date: aDate) {
                stepArchiveModel = model
            } else {
                stepArchiveModel = StepArchiveModel()
            }
            
            if model.day != 0 && model.steps.filter({ $0 > 0 }).isEmpty && stepArchiveModel.isEmpty == false {
                sucess?()
                return
            }
            
            stepArchiveModel.date = aDate.sqlDate()
            stepArchiveModel.adress = DeviceInfo.current().adress ?? ""
            stepArchiveModel.updateTime = Date().timeIntervalSince1970
            stepArchiveModel.steps = model.steps
            stepArchiveModel.updateData()
            
            sucess?()
        }
    }
    
}

// MARK: - 多天数据同步
extension BluetoothManager {
    
    public static let days: Int = 15
    
    /// 获取多天睡眠
    /// - Parameter date: 日期
    public func getSleepDatas(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetSleepData(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
  
    }
    
    fileprivate func recurseGetSleepData(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getSleepData(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetSleepData(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    /// 获取实时心率
    /// - Parameter date: 日期
    public func getTimingHeartRates(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetTimingHeartRates(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        
    }
    
    fileprivate func recurseGetTimingHeartRates(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getTimingHeartRate(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetTimingHeartRates(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    /// 获取全天 HRV
    public func getTimingHRVs(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetTimingHRVs(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
    }
    
    fileprivate func recurseGetTimingHRVs(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getTimingHRV(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetTimingHRVs(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    /// 获取全天血氧
    public func getTimingO2s(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
       // 递归获取
        recurseGetTimingO2s(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
    }
    
    fileprivate func recurseGetTimingO2s(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getTimingO2(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetTimingO2s(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    /// 多天活动历史数据
    public func getTrainingDatas(of startDate: Date = Date().sqlDate(), backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetTrainingDatas(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        
    }
    
    fileprivate func recurseGetTrainingDatas(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getTrainingData(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetTrainingDatas(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    /// 一天活动归档数据
    /// - Parameter date: 日期
    public func getStepArchiveDatas(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetStepArchiveDatas(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
    }
    
    fileprivate func recurseGetStepArchiveDatas(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getStepArchiveData(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetStepArchiveDatas(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    public func getSleepArchiveDatas(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetSleepArchiveDatas(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
    }
    
    fileprivate func recurseGetSleepArchiveDatas(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getSleepActivityArchiveData(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetSleepArchiveDatas(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    public func getSleepTemperatureDatas(of startDate: Date, backward days: Int = days, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        // 递归获取
        recurseGetSleepTemperatureDatas(of: startDate, to: startDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
    }
    
    fileprivate func recurseGetSleepTemperatureDatas(of startDate: Date, to date: Date, backward days: Int, forcedUpdate: Bool = false, sucess: (() ->Void)? = nil) {
        
        let dateComponents = dayComponents(of: startDate, to: date)
        if dateComponents >= days {
            sucess?()
            return
        }
        
        getSleepTemperatureData(of: startDate, to: date, forcedUpdate: forcedUpdate) {
          
            let nextDate = date - 1.days
            self.recurseGetSleepTemperatureDatas(of: startDate, to: nextDate, backward: days, forcedUpdate: forcedUpdate, sucess: sucess)
        }
        
    }
    
    
    public func getTrainingRecordDatas(ids: [Int], recordHandle: @escaping ((_ trainingModel: TrainingModel?, _ sportModel: CRPNewTrainingModel) ->Void)) {
        
        if ids.isEmpty {
            return
        }
        
        recurseGetTrainingRecordData(ids: ids, index: 0, recordHandle: recordHandle)
        
    }
    
    fileprivate func recurseGetTrainingRecordData(ids: [Int], index: Int, recordHandle: ((_ trainingModel: TrainingModel?, _ sportModel: CRPNewTrainingModel) ->Void)?) {
       
        if index >= ids.count {
            return
        }
        
        let id = ids[index]
        BluetoothManager.shared.getTrainingRecordData(id: id) {
            sportModel, error in
            // TODO: - 如果没有这条数据，就把这条数据存到数据库，同时使用这条数据；如果数据库有这条锻炼数据，那么开始判断
            if let dbModel = TrainingModel.model(of: sportModel.type.rawValue, startTime: sportModel.startTime) {
                //TODO: 如果戒指已经结束了，而手机数据库的还没结束，那么就同步戒指的除了开始时间以外的数据
                if sportModel.endTime != 0 && dbModel.endTime == 0 {
                    dbModel.endTime = sportModel.endTime
                    dbModel.vaildTime = sportModel.vaildTime
                    dbModel.step = sportModel.step
                    dbModel.distance = sportModel.distance
                    dbModel.kcal = sportModel.kcal
                    dbModel.heartRates = sportModel.heartRate
                    dbModel.heartRateAvg = sportModel.hrAvg
                    dbModel.hrAddress = sportModel.hrAddress
//                    dbModel.isDisconnected = false
                    dbModel.trainingState = 0
                    
                    // 标记已经同步过数据库
                    dbModel.syncRecord = 1
                    dbModel.updateData()
                    recordHandle?(dbModel, sportModel)
                    
                    let nextIndex = index + 1
                    self.recurseGetTrainingRecordData(ids: ids, index: nextIndex, recordHandle: recordHandle)
                    return
                }
                
                //TODO: 如果手机结束了，戒指没结束，用手机的数据，并发指令告诉戒指结束锻炼
                if dbModel.endTime != 0 && sportModel.endTime == 0 {
                    BluetoothManager.shared.setTraining(state: .end, type: CRPTrainingGoalType(rawValue: dbModel.goalType)!, goal: dbModel.goal)
//                    dbModel.isDisconnected = false
                    dbModel.trainingState = 0
                    // 标记已经同步过数据库
                    dbModel.syncRecord = 1
                    dbModel.updateData()
                    recordHandle?(dbModel, sportModel)
                    
                    let nextIndex = index + 1
                    self.recurseGetTrainingRecordData(ids: ids, index: nextIndex, recordHandle: recordHandle)
                    return
                }

                //TODO: 如果都没结束，对比一下心率等数据用多的一个，开始时间用手机的
                if dbModel.endTime == 0 && sportModel.endTime == 0 {
                    if sportModel.vaildTime > dbModel.vaildTime {
                        dbModel.vaildTime = sportModel.vaildTime
                    }
                    if sportModel.step > dbModel.step {
                        dbModel.step = sportModel.step
                    }
                    if sportModel.distance > dbModel.distance {
                        dbModel.distance = sportModel.distance
                    }
                    if sportModel.kcal > dbModel.kcal {
                        dbModel.kcal = sportModel.kcal
                    }
                    if sportModel.heartRate.count > dbModel.heartRates.count {
                        dbModel.heartRates = sportModel.heartRate
                    }
                    if sportModel.hrAvg != 0 {
                        dbModel.heartRateAvg = sportModel.hrAvg
                    }
                    if sportModel.hrAddress > dbModel.hrAddress {
                        dbModel.hrAddress = sportModel.hrAddress
                    }
                    if dbModel.trainingState == 2 {
                        BluetoothManager.shared.setTraining(state: .pause, type: CRPTrainingGoalType(rawValue: dbModel.goalType)!, goal: dbModel.goal)
                    }
                    
//                    dbModel.isDisconnected = false
                    // 标记已经同步过数据库
                    dbModel.syncRecord = 1
                    dbModel.updateData()
                    recordHandle?(dbModel, sportModel)
                    
                    let nextIndex = index + 1
                    self.recurseGetTrainingRecordData(ids: ids, index: nextIndex, recordHandle: recordHandle)
                    return
                }
                //TODO: 那么剩下的就是手机和戒指都结束了的数据，用手机的
//                dbModel.isDisconnected = false
                dbModel.trainingState = 0
                // 标记已经同步过数据库
                dbModel.syncRecord = 1
                dbModel.updateData()
                recordHandle?(dbModel, sportModel)
                
                let nextIndex = index + 1
                self.recurseGetTrainingRecordData(ids: ids, index: nextIndex, recordHandle: recordHandle)
                return
            }
            //TODO: 这里是手机没有戒指的这条数据，将这条数据存到数据库，然后使用
            let model = TrainingModel.model(of: sportModel.type.rawValue, startTime: sportModel.startTime) ?? TrainingModel()
            
            model.adress = DeviceInfo.current().adress ?? ""
            // 存储日期就是开始日期的年月日
            let date = Date(timeIntervalSince1970: TimeInterval(sportModel.startTime))
            model.date = date.sqlDate()
            model.startTime = sportModel.startTime
            model.endTime = sportModel.endTime
            model.vaildTime = sportModel.vaildTime
            model.type = sportModel.type.rawValue
            model.step = sportModel.step
            
            if model.locations.isEmpty || model.distance == 0 {
                // 有GPS的数据，以GPS的为准
                model.distance = sportModel.distance
            }
            model.kcal = sportModel.kcal
            model.heartRates = sportModel.heartRate
            if sportModel.goalType == .step {
                model.goalType = TrainingTypeContent.pace.rawValue // 步数代表配速
            } else {
                model.goalType = sportModel.goalType.rawValue
            }
            model.goal = sportModel.goal
            model.heartRateAvg = sportModel.hrAvg
            model.hrAddress = sportModel.hrAddress
            
            // 过滤异常数据,当前正在运动的不过滤
            var isFilterModel = false
            if let trainingType = TrainingType(rawValue: model.type), sportModel.id != 14, sportModel.endTime > 0 {
                
                let contents = trainingType.contents
                
                if contents.contains(.step) && model.step == 0 {
                    isFilterModel = true
                }
                
                if contents.contains(.calorie) && model.kcal == 0 {
                    isFilterModel = true
                }
            }
            
            if isFilterModel == false {
                
                // 标记已经同步过数据库
                model.syncRecord = 1
                model.updateData()
                
            } else {
                
                // 删除数据库异常数据
                if model.id != 0 {
                    model.delete()
                }
            }
            
            recordHandle?(model, sportModel)
            
            let nextIndex = index + 1
            self.recurseGetTrainingRecordData(ids: ids, index: nextIndex, recordHandle: recordHandle)
            
        }
        
    }
    
}

// MARK: - 单次测量数据同步
extension BluetoothManager {
    
    public func getHeartRecordDatas(sucess: (() ->Void)? = nil) {
        
        BluetoothManager.shared.getHeartRecordData { heartRecordModels, error in
            
            heartRecordModels.forEach {
                
                if $0.time > 0 && $0.value > 0 {
                    
                    let model = SingleHeartRateModel.aModel(from: Double($0.time)) ?? SingleHeartRateModel()
                    model.adress = DeviceInfo.current().adress ?? ""
                    model.date = Date(timeIntervalSince1970: TimeInterval($0.time)).sqlDate()
                    model.heartRate = $0.value
                    model.end = Double($0.time)
                    
                    model.updateData()
                }
            }
            
            if !heartRecordModels.isEmpty {
                sucess?()
            }
             
        }
    }
    
    public func getO2RecordDatas(sucess: (() ->Void)? = nil) {
        
        
        BluetoothManager.shared.getO2RecordData { o2RecordModels, error in
            
            o2RecordModels.forEach {
                
                if $0.time > 0 && $0.value > 0 {
                    
                    let model = SingleBloodOxygenModel.aModel(from: Double($0.time)) ?? SingleBloodOxygenModel()
                    model.adress = DeviceInfo.current().adress ?? ""
                    model.date = Date(timeIntervalSince1970: TimeInterval($0.time)).sqlDate()
                    model.o2 = $0.value
                    model.end = Double($0.time)
                    
                    model.updateData()
                    
                }
            }
            
            if !o2RecordModels.isEmpty {
                sucess?()
            }
            
        }
    }
    
    public func getHRVRecordDatas(sucess: (() ->Void)? = nil) {
        
        BluetoothManager.shared.getHRVRecord { hrvRecordModels, error in
            
            hrvRecordModels.forEach {
                
                if $0.time > 0 && $0.hrv > 0 {
                    
                    let hrvModel = SingleHRVModel.aModel(from: Double($0.time)) ?? SingleHRVModel()
                    hrvModel.adress = DeviceInfo.current().adress ?? ""
                    hrvModel.date = Date(timeIntervalSince1970: TimeInterval($0.time)).sqlDate()
                    hrvModel.hrv = $0.hrv
                    hrvModel.end = Double($0.time)
                    
                    hrvModel.updateData()
                }
                
            }
            
            if !hrvRecordModels.isEmpty {
                sucess?()
            }
            
        }
        
    }
    
    public func getStressRecordDatas(sucess: (() ->Void)? = nil) {
        
        BluetoothManager.shared.getStressRecord { stressRecordModel, error in
            
            stressRecordModel.forEach {
                
                if $0.time > 0 && $0.stress > 0 {
                    
                    let stressModel = SingleStressModel.aModel(from: Double($0.time)) ?? SingleStressModel()
                    stressModel.adress = DeviceInfo.current().adress ?? ""
                    stressModel.date = Date(timeIntervalSince1970: TimeInterval($0.time)).sqlDate()
                    stressModel.stress = $0.stress
                    stressModel.end = Double($0.time)
                    
                    stressModel.updateData()
                }
            }
            
            if !stressRecordModel.isEmpty {
                sucess?()
            }
        }
    }
    
}

// MARK: - 恢复出厂设置
extension BluetoothManager {
    
    // 设备恢复出厂设置
    public func resetDevice() {
        
        self.reUpdateInFactoryDataReseted()
        self.reset()
        
    }
    
    /// 恢复出厂设置之前调用
    public func reUpdateInFactoryDataReseted() {
        
        DeviceInfo.current().clear()
        
//        // 活动归档是半小时一个数据，恢复出厂设置需要去同步
//        if let activityModel = StepArchiveModel.day(date: date) {
//            activityModel.updateTime = date.timeIntervalSince1970 - 2000
//            activityModel.updateData()
//        }
//
//
//        // 心率是半小时一个数据，恢复出厂设置需要去同步
//        if let heartRateModel = HeartRateModel.day(date: date) {
//            heartRateModel.updateTime = date.timeIntervalSince1970 - 2000
//            heartRateModel.updateData()
//
//        }
        
    }
    
}

extension BluetoothManager {
    
    
    /// 数组分割再获取真实值
    /// - Parameters:
    ///   - data: 数组
    ///   - from: 起始位置
    ///   - range: 间隔，注意：一定能被data 整数，不然尾部数据会被舍弃
    /// - Returns: 真实数据数组
    public func stride(data: [Int], from: Int, range: Int) ->[Int] {
        
        #if DEBUG
        if data.endIndex % range > 0 {
           assert(false, "数组长度与分割个数无法被整除，确定是你需要的吗？")
        }
//
        #endif
    
        let heartArray = Swift.stride(from: from, to: data.endIndex - (data.endIndex % range), by: range).map {
            
            Array(data[$0...$0+(range - 1)])
        }
        
        // 过滤出真实值
        let realDataArray = heartArray.compactMap { arr ->Int in
        
            guard let h = arr.filter({ $0 > 0 }).last else {
                return 0
            }
            return h
        }
        
       return realDataArray
        
    }
    
}

